<?php
namespace soa\partner\sto;

use artisan\http;
use soa\parter\sto\StoDelivery;

class StoOperate
{
    /**
     * @var
     */
    private $scanInfo = [
        'cm_code'   => '',
        'shop_name' => '',
    ];

    /**
     * @var int
     */
    private $waybillType = 3;

    /**
     * @var array
     */
    public $operateMap = [
        '收件'  => 'collect',
        '派件'  => 'deliver',
        '签收'  => 'sign',
        '问题件' => 'question_scan',
        '到件'  => 'arrive',
        '发件'  => 'from_to',
    ];

    private $ignore = 0;

    public function __construct($scanInfo = [], $waybillType = 3)
    {
//        $this->ignore = 1;//屏蔽查件

        $scanInfo and $this->scanInfo = $scanInfo;
        $waybillType and $this->waybillType = $waybillType;
    }

    /**
     * @param $waybillNos
     * @param bool $parse
     * @return array
     */
    public function getOperateIgnore(&$waybillNos,$parse = true)
    {
        $return = [];

        return $parse ? $this->parse($return,$waybillNos) : $return;
    }

    /**
     * 查询运单号物流详情(内部接口)
     *
     * @param $waybillNos
     * @param bool $parse
     * @return array
     */
    public function getOperate(&$waybillNos,$parse = true)
    {
        $return = [];

        if(empty($this->ignore)){
            $waybillNoBlocks = array_chunk($waybillNos, 5);
            foreach($waybillNoBlocks as $waybillNoBlock){
                $query = array(
                    'company'    => 'sto',
                    'express_no' => implode(',', $waybillNoBlock),
                    'params'     => '["GetOperate"]',
                    'channel'    => 'pda-batch'
                );
                $url = 'http://express.interface.kuaidihelp.com/multinfo.php';
                $result = http::get($url, $query, ['TIMEOUT' => 5]);
                if(!empty($result)) {
                    $flowResult = json_decode($result, true);
                    if(json_last_error() == 0 && $flowResult['GetOperate'] !== null) { //=== null表示发生网络错误导致未获得流转信息
                        //如果是单个单号的，返回结果格式不一致，将其转化为与多个查询相同的格式
                        if(count($waybillNoBlock) == 1){
                            $flowResult['GetOperate'] = array(array_pop($waybillNoBlock) => $flowResult['GetOperate']);
                        }

                        $return = $return + $flowResult['GetOperate'];
                    }
                }
            }
        }
//        $return = json_decode('{"568007150053":{"arrive":{"shop_name":"\u4e0a\u6d77\u9752\u6d66\u516c\u53f8","shop_id":"912","time":"2017-07-05 15:07:14"},"deliver":{"shop_name":"\u4e0a\u6d77\u9752\u6d66\u516c\u53f8","shop_id":"912","time":"2017-07-05 15:07:39","courier":"\u9ad8\u82f1\u534e"},"sign":{"shop_name":null,"shop_id":null,"time":"2017-07-05 15:09:12"}}}',true);
//        $return = json_decode('{"568007150057":{"deliver":{"shop_name":"\u4e0a\u6d77\u9752\u6d66\u516c\u53f8","shop_id":"912","time":"2017-07-05 15:07:39","courier":"\u9ad8\u82f1\u534e"}}}',true);

        return $parse ? $this->parse($return,$waybillNos) : $return;
    }

    /**
     * 查询运单号物流详情(申通查件接口)
     *
     * @param $waybillNos
     * @param bool $parse
     * @return array
     */
    public function getOperateNew(&$waybillNos,$parse = true)
    {
        $return = [];

        if(empty($this->ignore)) {
            $waybillNoBlocks = array_chunk($waybillNos, 20);
            foreach ($waybillNoBlocks as $waybillNoBlock) {
                $result = $this->getExpressOperate($waybillNoBlock);
                if (!empty($result)) {
                    $return = $return + $result;
                }
            }
        }

        return $parse ? $this->parse($return,$waybillNos) : $return;
    }

    /**
     * @param $data
     * @param $waybillNos
     * @param $isFix
     * @return array
     */
    public function parse(&$data,&$waybillNos,$isFix = 0)
    {
        $return = [];

        if($waybillNos && is_array($waybillNos)){
            foreach($waybillNos as $k=>$waybillNo){
                if(isset($data[$waybillNo]) && !empty($data[$waybillNo])){
                    $res = $this->filter($data[$waybillNo],$isFix,$waybillNo);
                    if($res['type']) {
                        $return[$res['type']][$waybillNo] = in_array($res['type'],['signed','noFix']) ? $k : ['index'=>$k,'info'=>$res['result']];
                    }
                }else{
                    $return['noResult'][$waybillNo] = $k;
                }
            }
        }

        return $return;
    }

    /**
     * @param $operate
     * @param $isFix
     * @param string $waybillNo
     * @return array
     */
    public function filter(&$operate,$isFix,$waybillNo='')
    {
        $return = [
            'type'   => '',
            'result' => '',
        ];
        if(2 == $this->waybillType){
            if(!empty($operate['arrive']) || !empty($operate['sign'])){
                $return['type'] = 'noFix';
                $return['result']    = 1;
            }else{
                $return['type']   = 'fix';
                $return['result'] = $operate;
            }
        }elseif(3 == $this->waybillType){
            if(!empty($operate['sign'])){
                $return['type']   = 'signed';
                $return['result'] = 1;
            }elseif(!empty($operate['arrive']['shop_name'])){ //这是最近一条到件扫描的网点名称
                if(!empty($this->scanInfo['shop_name']) && $this->scanInfo['shop_name'] == $operate['arrive']['shop_name']){
                    $return['type'] = 'noFix';
                    $return['result']    = 1;
                }else{
                    if($isFix){
                        $return['type']   = 'fix';
                        $return['result'] = $operate;
                    }else{
logDebug('运单号：'.$waybillNo.'——快递员所在网点：'.$this->scanInfo['shop_name'].'——运单号到件网点：'.$operate['arrive']['shop_name'],'sto_express_arrive_error',true);
                        $return['type']   = 'shopError1';
                        $return['result'] = $operate;
                    }
                }
            }elseif(empty($operate['arrive'])){ //没有到件扫描
                if($isFix){
                    $return['type']   = 'fix';
                    $return['result'] = $operate;
                }else{
logDebug('运单号：'.$waybillNo.'——快递员所在网点：'.$this->scanInfo['shop_name'].'——运单号物流详情：'.json_encode($operate,JSON_UNESCAPED_UNICODE),'sto_express_no_arrive',true);
                    $return['type']   = 'shopError2';
                    $return['result'] = $operate;
                }
            }
        }elseif(6 == $this->waybillType){
            if(!empty($operate['collect'])){
                $return['type'] = 'noFix';
                $return['result']    = 1;
            }else{
                $return['type']   = 'fix';
                $return['result'] = $operate;
            }
        }

        return $return;
    }

    /**
     * @param $waybillNos
     * @return array
     */
    private function getExpressOperate($waybillNos)
    {
        $res = StoDelivery::getExpressOperate($waybillNos);
        if($res && is_array($res)){
            $result = [];
            foreach($res as $waybill){
                if($waybill['ScanList']){
                    $operate = [];
                    $operate['weight'] = 0;
                    foreach($waybill['ScanList'] as $scan){
                        //解析出各种操作类型最近一次出现的时间、网点
                        if($scan['ScanType']){
                            if($scan['Weight'] && $scan['Weight'] > $operate['weight']){
                                $operate['weight'] = (float)$scan['Weight'];
                            }

                            if(isset($this->operateMap[$scan['ScanType']])){
                                $type = $this->operateMap[$scan['ScanType']];
                            }else{
                                $type = $scan['ScanType'];
                            }

                            //揽件操作取第一条记录，其他操作取最后一条记录
                            if ($scan['ScanType'] != '收件' ||
                                ($scan['ScanType'] == '收件' && !isset($operate[$type]))
                            )
                            {
                                $operate[$type] = [
                                    'shop_name' => $scan['UploadSiteName'],
                                    'shop_id'   => $scan['UploadSiteId'],
                                    'time'      => $scan['ScanDate']
                                ];
                            }

                            if ($scan['ScanType'] == '派件') {    //派件操作同时返回扫描快递员id
                                $operate[$type]['courier'] = $scan['PickerId'];
                                $operate[$type]['courier_code'] = $scan['PickerName'];
                            }

                            if($scan['ScanType'] == '问题件') {    //问题件操作同时返回问题件类型
                                $operate[$type]['reason'] = $scan['Remark'];
                            }
                        }
                    }
                    $result[$waybill['Id']] = $operate;
                }
            }
            return $result;
        }
        return [];
    }
}